/**
 * 项目管理工具 - IntelliMark适配版
 * 提供文档项目和章节管理功能
 */

import { BaseTool, ToolResult, ProjectAction } from "../../types/tools";
import { v4 as uuidv4 } from 'uuid';
import * as fs from 'fs-extra';
import * as path from 'path';

// 文档项目接口
export interface DocumentProject {
  id: string;
  name: string;
  description: string;
  createdAt: Date;
  updatedAt: Date;
  settings: ProjectSettings;
  chapters: Chapter[];
  metadata: Record<string, any>;
}

// 章节接口
export interface Chapter {
  id: string;
  projectId: string;
  title: string;
  content: string;
  order: number;
  wordCount: number;
  createdAt: Date;
  updatedAt: Date;
  status: 'draft' | 'in_progress' | 'completed' | 'archived';
  tags: string[];
  metadata: Record<string, any>;
}

// 项目设置
export interface ProjectSettings {
  defaultLanguage: string;
  autoSave: boolean;
  backupEnabled: boolean;
  template: string;
  writingGoals: {
    dailyWords: number;
    targetDate?: Date;
  };
}

// 项目管理配置
export interface ProjectManagementConfig {
  storagePath: string;
  enableBackups: boolean;
  backupInterval: number; // 小时
  maxBackups: number;
}

export class ProjectManagementTool extends BaseTool {
  private config: ProjectManagementConfig;
  private projects: Map<string, DocumentProject> = new Map();
  private chapters: Map<string, Chapter> = new Map();

  constructor(config: Partial<ProjectManagementConfig> = {}) {
    super();

    this.name = 'project-management';
    this.description = 'IntelliMark项目管理工具，负责管理文档项目、章节结构和写作进度';
    this.category = 'projectManagement';
    this.enabled = true;
    this.requiresAuth = false;

    this.config = {
      storagePath: './projects',
      enableBackups: true,
      backupInterval: 24,
      maxBackups: 10,
      ...config,
    };

    this.parameters = [
      {
        name: 'action',
        type: 'string' as const,
        description: '项目操作类型',
        required: true,
        validation: {
          enum: ['create', 'read', 'update', 'delete', 'list', 'search', 'backup', 'restore'],
        },
      },
      {
        name: 'projectId',
        type: 'string' as const,
        description: '项目ID',
        required: false,
      },
      {
        name: 'chapterId',
        type: 'string' as const,
        description: '章节ID',
        required: false,
      },
      {
        name: 'data',
        type: 'object' as const,
        description: '操作数据',
        required: false,
      },
    ];
  }

  async execute(input: any): Promise<ToolResult> {
    const startTime = Date.now();
    const requestId = uuidv4();

    try {
      // 验证输入参数
      const validatedInput = this.validateInput(input);

      // 执行项目操作
      const result = await this.performProjectAction(validatedInput);

      const executionTime = Date.now() - startTime;

      return {
        success: true,
        data: result,
        metadata: {
          executionTime,
          action: validatedInput.action,
          requestId,
          totalProjects: this.projects.size,
          totalChapters: this.chapters.size,
        },
      };

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error);

      return {
        success: false,
        error: errorMessage,
        metadata: {
          executionTime: Date.now() - startTime,
          requestId,
        },
      };
    }
  }

  private validateInput(input: any): { action: ProjectAction; projectId?: string; chapterId?: string; data?: any } {
    if (!input.action) {
      throw new Error('action参数是必需的');
    }

    const validActions: ProjectAction[] = ['create', 'read', 'update', 'delete', 'list', 'search', 'backup', 'restore'];
    if (!validActions.includes(input.action)) {
      throw new Error(`无效的action: ${input.action}`);
    }

    const validated: any = {
      action: input.action,
    };

    // 根据操作类型验证必需参数
    switch (input.action) {
      case 'create':
        if (!input.data) {
          throw new Error('create操作需要data参数');
        }
        validated.data = input.data;
        break;

      case 'read':
      case 'update':
      case 'delete':
        if (!input.projectId) {
          throw new Error(`${input.action}操作需要projectId参数`);
        }
        validated.projectId = input.projectId;
        if (input.chapterId) {
          validated.chapterId = input.chapterId;
        }
        if (input.action === 'update' && input.data) {
          validated.data = input.data;
        }
        break;

      case 'list':
      case 'search':
        // 这些操作是可选参数
        if (input.data) {
          validated.data = input.data;
        }
        break;

      case 'backup':
        if (!input.projectId) {
          throw new Error('backup操作需要projectId参数');
        }
        validated.projectId = input.projectId;
        break;

      case 'restore':
        if (!input.data?.backupPath) {
          throw new Error('restore操作需要data.backupPath参数');
        }
        validated.data = input.data;
        break;
    }

    return validated;
  }

  private async performProjectAction(params: {
    action: ProjectAction;
    projectId?: string;
    chapterId?: string;
    data?: any;
  }): Promise<any> {
    switch (params.action) {
      case 'create':
        return this.createProject(params.data);

      case 'read':
        if (params.chapterId) {
          return this.getChapter(params.projectId!, params.chapterId);
        }
        return this.getProject(params.projectId!);

      case 'update':
        if (params.chapterId) {
          return this.updateChapter(params.projectId!, params.chapterId, params.data);
        }
        return this.updateProject(params.projectId!, params.data);

      case 'delete':
        if (params.chapterId) {
          return this.deleteChapter(params.projectId!, params.chapterId);
        }
        return this.deleteProject(params.projectId!);

      case 'list':
        return this.listProjects(params.data);

      case 'search':
        return this.searchProjects(params.data);

      case 'backup':
        return this.backupProject(params.projectId!);

      case 'restore':
        return this.restoreProject(params.data.backupPath);

      default:
        throw new Error(`不支持的操作: ${params.action}`);
    }
  }

  private createProject(data: any): DocumentProject {
    const project: DocumentProject = {
      id: data.id || uuidv4(),
      name: data.name || 'Untitled Project',
      description: data.description || '',
      createdAt: new Date(),
      updatedAt: new Date(),
      settings: {
        defaultLanguage: data.settings?.defaultLanguage || 'zh-CN',
        autoSave: data.settings?.autoSave !== false,
        backupEnabled: data.settings?.backupEnabled !== false,
        template: data.settings?.template || 'default',
        writingGoals: {
          dailyWords: data.settings?.writingGoals?.dailyWords || 500,
          targetDate: data.settings?.writingGoals?.targetDate,
        },
        ...data.settings,
      },
      chapters: [],
      metadata: data.metadata || {},
    };

    // 创建默认章节
    if (data.createDefaultChapter !== false) {
      const defaultChapter: Chapter = {
        id: uuidv4(),
        projectId: project.id,
        title: '第一章',
        content: data.defaultChapterContent || '',
        order: 1,
        wordCount: 0,
        createdAt: new Date(),
        updatedAt: new Date(),
        status: 'draft',
        tags: [],
        metadata: {},
      };

      project.chapters.push(defaultChapter);
      this.chapters.set(defaultChapter.id, defaultChapter);
    }

    this.projects.set(project.id, project);

    // 保存到文件系统
    this.saveProjectToFile(project);

    return project;
  }

  private getProject(projectId: string): DocumentProject | null {
    const project = this.projects.get(projectId);
    if (!project) {
      // 尝试从文件加载
      return this.loadProjectFromFile(projectId);
    }
    return project;
  }

  private getChapter(projectId: string, chapterId: string): Chapter | null {
    // 首先确保项目已加载
    const project = this.getProject(projectId);
    if (!project) {
      throw new Error(`项目不存在: ${projectId}`);
    }

    const chapter = this.chapters.get(chapterId);
    if (!chapter || chapter.projectId !== projectId) {
      throw new Error(`章节不存在: ${chapterId}`);
    }

    return chapter;
  }

  private updateProject(projectId: string, data: any): DocumentProject | null {
    const project = this.getProject(projectId);
    if (!project) {
      throw new Error(`项目不存在: ${projectId}`);
    }

    // 更新项目信息
    Object.assign(project, data);
    project.updatedAt = new Date();

    // 更新设置
    if (data.settings) {
      project.settings = { ...project.settings, ...data.settings };
    }

    this.projects.set(projectId, project);
    this.saveProjectToFile(project);

    return project;
  }

  private updateChapter(projectId: string, chapterId: string, data: any): Chapter | null {
    const chapter = this.getChapter(projectId, chapterId);
    if (!chapter) {
      throw new Error(`章节不存在: ${chapterId}`);
    }

    // 更新章节信息
    Object.assign(chapter, data);
    chapter.updatedAt = new Date();

    // 重新计算字数
    if (data.content !== undefined) {
      chapter.wordCount = this.countWords(data.content);
    }

    this.chapters.set(chapterId, chapter);

    // 更新项目的更新时间
    const project = this.projects.get(projectId);
    if (project) {
      project.updatedAt = new Date();
      this.saveProjectToFile(project);
    }

    return chapter;
  }

  private deleteProject(projectId: string): boolean {
    const project = this.projects.get(projectId);
    if (!project) {
      return false;
    }

    // 删除所有章节
    project.chapters.forEach(chapter => {
      this.chapters.delete(chapter.id);
    });

    // 删除项目
    this.projects.delete(projectId);

    // 删除文件
    const projectPath = path.join(this.config.storagePath, `${projectId}.json`);
    if (fs.existsSync(projectPath)) {
      fs.unlinkSync(projectPath);
    }

    return true;
  }

  private deleteChapter(projectId: string, chapterId: string): boolean {
    const project = this.getProject(projectId);
    if (!project) {
      throw new Error(`项目不存在: ${projectId}`);
    }

    const chapterIndex = project.chapters.findIndex(c => c.id === chapterId);
    if (chapterIndex === -1) {
      return false;
    }

    // 从项目中移除章节
    project.chapters.splice(chapterIndex, 1);

    // 删除章节
    this.chapters.delete(chapterId);

    // 重新排序
    project.chapters.forEach((chapter, index) => {
      chapter.order = index + 1;
    });

    this.saveProjectToFile(project);

    return true;
  }

  private listProjects(filters?: any): DocumentProject[] {
    const projects = Array.from(this.projects.values());

    if (!filters) {
      return projects;
    }

    return projects.filter(project => {
      if (filters.status && project.metadata.status !== filters.status) {
        return false;
      }
      if (filters.searchTerm && !this.matchesSearchTerm(project, filters.searchTerm)) {
        return false;
      }
      if (filters.tags && !filters.tags.some((tag: string) => project.metadata.tags?.includes(tag))) {
        return false;
      }
      return true;
    });
  }

  private searchProjects(query: any): { projects: DocumentProject[]; chapters: Chapter[] } {
    const searchTerm = query.searchTerm || '';
    const projects = this.listProjects({ searchTerm });

    // 搜索章节
    const chapters = Array.from(this.chapters.values()).filter(chapter =>
      chapter.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
      chapter.content.toLowerCase().includes(searchTerm.toLowerCase()) ||
      chapter.tags.some(tag => tag.toLowerCase().includes(searchTerm.toLowerCase()))
    );

    return { projects, chapters };
  }

  private async backupProject(projectId: string): Promise<string> {
    const project = this.getProject(projectId);
    if (!project) {
      throw new Error(`项目不存在: ${projectId}`);
    }

    const backupPath = path.join(this.config.storagePath, 'backups');
    await fs.ensureDir(backupPath);

    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const filename = `${projectId}_backup_${timestamp}.json`;
    const fullPath = path.join(backupPath, filename);

    const backupData = {
      project,
      chapters: project.chapters.map(chapterId =>
        this.chapters.get(chapterId)
      ).filter(Boolean),
      backupDate: new Date(),
      version: '1.0',
    };

    await fs.writeJSON(fullPath, backupData, { spaces: 2 });

    // 清理旧备份
    await this.cleanupOldBackups();

    return fullPath;
  }

  private async restoreProject(backupPath: string): Promise<DocumentProject> {
    if (!fs.existsSync(backupPath)) {
      throw new Error(`备份文件不存在: ${backupPath}`);
    }

    const backupData = await fs.readJSON(backupPath);

    if (!backupData.project || !backupData.chapters) {
      throw new Error('无效的备份文件格式');
    }

    // 恢复项目
    const project = backupData.project as DocumentProject;
    this.projects.set(project.id, project);

    // 恢复章节
    backupData.chapters.forEach((chapter: Chapter) => {
      this.chapters.set(chapter.id, chapter);
    });

    // 保存到当前存储
    this.saveProjectToFile(project);

    return project;
  }

  private saveProjectToFile(project: DocumentProject): void {
    const projectPath = path.join(this.config.storagePath, `${project.id}.json`);
    fs.ensureDirSync(this.config.storagePath);
    fs.writeJSONSync(projectPath, project, { spaces: 2 });
  }

  private loadProjectFromFile(projectId: string): DocumentProject | null {
    const projectPath = path.join(this.config.storagePath, `${projectId}.json`);

    if (!fs.existsSync(projectPath)) {
      return null;
    }

    try {
      const project = fs.readJSONSync(projectPath) as DocumentProject;
      this.projects.set(projectId, project);

      // 加载章节
      project.chapters.forEach(chapter => {
        this.chapters.set(chapter.id, chapter);
      });

      return project;
    } catch (error) {
      console.error(`Failed to load project ${projectId}:`, error);
      return null;
    }
  }

  private async cleanupOldBackups(): Promise<void> {
    if (!this.config.enableBackups) {
      return;
    }

    const backupPath = path.join(this.config.storagePath, 'backups');
    if (!fs.existsSync(backupPath)) {
      return;
    }

    const files = await fs.readdir(backupPath);
    const backupFiles = files
      .filter(file => file.endsWith('.json'))
      .map(file => ({
        name: file,
        path: path.join(backupPath, file),
        time: fs.statSync(path.join(backupPath, file)).mtime,
      }))
      .sort((a, b) => b.time.getTime() - a.time.getTime());

    // 保留最新的N个备份
    if (backupFiles.length > this.config.maxBackups) {
      const filesToDelete = backupFiles.slice(this.config.maxBackups);

      for (const file of filesToDelete) {
        await fs.unlink(file.path);
      }
    }
  }

  private matchesSearchTerm(project: DocumentProject, searchTerm: string): boolean {
    const term = searchTerm.toLowerCase();
    return (
      project.name.toLowerCase().includes(term) ||
      project.description.toLowerCase().includes(term) ||
      project.metadata.tags?.some((tag: string) => tag.toLowerCase().includes(term))
    );
  }

  private countWords(text: string): number {
    // 简单的字数统计，支持中英文
    const chineseChars = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
    const englishWords = (text.match(/[a-zA-Z]+/g) || []).length;
    return chineseChars + englishWords;
  }

  // 公共方法
  public getProjectStats(projectId: string): {
    totalWords: number;
    chapterCount: number;
    completedChapters: number;
    progress: number;
    lastUpdated: Date;
  } | null {
    const project = this.getProject(projectId);
    if (!project) {
      return null;
    }

    const chapters = project.chapters.map(id => this.chapters.get(id)).filter(Boolean) as Chapter[];
    const totalWords = chapters.reduce((sum, chapter) => sum + chapter.wordCount, 0);
    const completedChapters = chapters.filter(c => c.status === 'completed').length;
    const progress = chapters.length > 0 ? (completedChapters / chapters.length) * 100 : 0;

    return {
      totalWords,
      chapterCount: chapters.length,
      completedChapters,
      progress,
      lastUpdated: project.updatedAt,
    };
  }

  public async loadAllProjects(): Promise<void> {
    if (!fs.existsSync(this.config.storagePath)) {
      return;
    }

    const files = await fs.readdir(this.config.storagePath);
    const projectFiles = files.filter(file => file.endsWith('.json') && !file.includes('backup'));

    for (const file of projectFiles) {
      const projectId = path.basename(file, '.json');
      this.loadProjectFromFile(projectId);
    }
  }

  public updateConfig(newConfig: Partial<ProjectManagementConfig>): void {
    this.config = { ...this.config, ...newConfig };
  }

  // 便捷方法
  public async createChapter(projectId: string, title: string, content: string = ''): Promise<Chapter> {
    const project = this.getProject(projectId);
    if (!project) {
      throw new Error(`项目不存在: ${projectId}`);
    }

    const chapter: Chapter = {
      id: uuidv4(),
      projectId,
      title,
      content,
      order: project.chapters.length + 1,
      wordCount: this.countWords(content),
      createdAt: new Date(),
      updatedAt: new Date(),
      status: 'draft',
      tags: [],
      metadata: {},
    };

    project.chapters.push(chapter.id);
    this.chapters.set(chapter.id, chapter);
    project.updatedAt = new Date();

    this.saveProjectToFile(project);

    return chapter;
  }

  public moveChapter(projectId: string, chapterId: string, newOrder: number): boolean {
    const project = this.getProject(projectId);
    if (!project) {
      throw new Error(`项目不存在: ${projectId}`);
    }

    const chapterIndex = project.chapters.findIndex(id => id === chapterId);
    if (chapterIndex === -1) {
      return false;
    }

    // 移动章节
    const [chapterIdToMove] = project.chapters.splice(chapterIndex, 1);
    project.chapters.splice(newOrder - 1, 0, chapterIdToMove);

    // 重新排序
    project.chapters.forEach((id, index) => {
      const chapter = this.chapters.get(id);
      if (chapter) {
        chapter.order = index + 1;
      }
    });

    project.updatedAt = new Date();
    this.saveProjectToFile(project);

    return true;
  }
}

// 导出便捷函数
export const createProjectManagementTool = (config?: Partial<ProjectManagementConfig>): ProjectManagementTool => {
  return new ProjectManagementTool(config);
};

// 默认实例
export const defaultProjectManagementTool = new ProjectManagementTool();